'use strict'
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bcrypt = require('bcryptjs');
mongoose.set('useCreateIndex', true);
const utils = require('../utils/utils');
const deviceSchema = new Schema({
  devicetoken: String,
  platform: Number//1 ios, 2 android, 3 winphone, 4 others
});

const abuseReportSchema = new Schema({
  reporter: String,//userCode
  reportime: Number,
  content: {type: String, default: ''},
  photos: [String]
})

const shareSchema = new Schema({
  shareTime: Number,
  userCode: String
})

/**
 * 问题1：//这个phone不一定是手机号码
 * 问题2： //这个name和app user的name也不一定一样
 * 问题3：如果不是app user 那还要不要保留？按道理没有保留的必要
 * 但保留也可以经常的发邀请
 * 问题4：多帐号电话号码簿的重复性很高。怎么处理？
 * 注意1：要剔除自己的电话号码？
 * 注意2：当前的MODEL已经有所改变。要注意合并只能合并ADDRESSBOOK
 */
const addressBookSchema = new Schema({
  userCode: {type: String, default: ''},
  countryCode: {type: String, default: ''},
  mobile: {type: String, default: ''},
  name: {type: String, default: ''},
  isAppUser: {type: Boolean, default: false},
  followship: {type: Number, defaul: 0}
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
    }
  }
});

const imageSchema = new Schema({
  origin: {type: String, default: ''},
  medium: {type: String, default: ''},
  small: {type: String, default: ''},
  uploadedTime: {type: Number, default: 0}
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
    }
  }
});

const tokboxTypeModel = ['broadcast', 'voip'];
const emptyImage = {
  "origin": "",
  "medium": "",
  "small": "",
  "uploadTime": 0
}
const tokboxHistorySchema = new Schema({
  sessionId: String,
  userCode: String,
  receiver: String,
  startTime: Number,
  endTime: Number,
  type: String,//broadcast, voip
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

/**
 * 视频平台webhook模型
 */
const tokboxSchema = new Schema({
  sessionId: String,
  token: String,
  type: {type: String, enum: ['broadcast', 'voip', '0', '1', ''], default: 'broadcast'},//tokbox类型，0:直播 1: voip voice 2:voip video
  expired: {type: Number, default: 0},
  projectId: {type: String, default: ''},
  event: {type: String, default: ''},//最新发生事件
  reason: {type: String, default: ''},
  status: {type: String, enum: ['on', 'off', ''], default: ''},
  timestamp: {type: Number, default: 0},//最新状态更新时间
  connection://NOt used
    {
      id: String,
      createdAt: {type: Number, default: 0},
      data: String
    },
  stream: { //stream property
    id: String,
    connection:
      {
        id: String,
        createdAt: {type: Number, default: 0},
        data: String
      },
    createdAt: {type: Number, default: 0},
    name: {type: String, default: ''},
    videoType: String
  },
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

/**
 * 交易模型设计
 */
const transactionSchema = new Schema({
  payer: String,
  payee: String,
  transTime: Number,
  status: Boolean,
  resourceId: String,
  amount: {type: Number, default: 0}
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

/**
 * 收藏模型
 */
const favouriteSchema = new Schema({
  type: {type: String, enum: ['moment', 'video']},
  resourceId: String,//video resourceId(暂考虑video收藏)
  userCodeList: [String]
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});
const musicSchema = new Schema({
  musicid: String,
  icon: String,
  link: String,
  name: String,
  duration: {type: Number, default: 0},
  start: {type: Number, default: 0},
  end: {type: Number, default: 0},
  author: {type: String, default: ''},
  tags: [String],
  category: {type: String, default: ''},
  title: {type: String, default: ''}
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

const avatarSchema = new Schema({
  origin: {type: String, default: ''},
  uploadTime: {type: Number, default: 0},
  medium: {type: String, default: ''},
  small: {type: String, default: ''}
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
    }
  }
});

/**
 * 本模型只作为参考
 */
const creatorSchema = new Schema({
  userCode: {type: String, default: ''},
  name: {type: String, default: ''},
  nickname: {type: String, default: ''},
  avatar: {type: imageSchema, default: emptyImage},
  commentCount: {type: Number, default: 0},
  videoCount: {type: Number, default: 0},
  momentCount: {type: Number, default: 0},
  followingCount: {type: Number, default: 0},
  followerCount: {type: Number, default: 0}
});

/*评论模型*/
const commentSchema = new Schema({
  c_owner: {type: Schema.Types.ObjectId, ref: 'user'},
  c_subComments: [{type: Schema.Types.ObjectId, ref: 'comment'}],

  resourceId: String,//资源id
  commentId: String,//评论id
  parentId: String,//评论的资源或其他评论的id.冗余字段，方便反向查找资源
  childrenIds: [String],//子评论id列表
  body: {type: String, default: ''},//评论内容
  postTime: {type: Number, default: 0},//评论时间,
  replyTo: {type: String, default: ''},//被评论者userCode
  replyToName: {type: String, default: ''},//被评论者名字
  userCode: {type: String, default: ''},
  creator: {type: creatorSchema, default: {}},
  likes: [String]
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

const giftSchema = new Schema({
  giftid: String,
  animImage: String,
  image: {type: String, default: ''},
  name: {type: String, default: ''},
  price: {type: Number, default: 0},
  score: String,
  category: {type: String, default: ''},
  sort: String,
  costType: {type: String, default: ''},
  weight: {type: String, default: ''},
  filename: {type: String, default: ''}
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

//现在只用于直播
const publishedResourceSchema = new Schema({
  //combined uuid for the broadcast resource
  isLive: {type: Boolean, default: false},
  broadcastId: String,//the value come from the tokbox当前和resourceId一样
  resourceId: {type: String, default: ''},//broadcastId
  resourceUri: {type: String, default: ''},//直播间网址
  roomId: {type: String, default: ''},//当前（20181123）未实现
  channelId: {type: String, default: ''},//直播间聊天室id
  category: {type: String, default: ''},//直播分类
  coverImage: {type: imageSchema, default: emptyImage},//直播室封面/个人档案背景图
  favourites: [String], //收藏者uuid
  shares: [shareSchema],//分享者uuid
  likes: [String],      //喜欢（点赞）者uuid
  audienceCount: {type: Number, default: 0},//当前直播室人数统计。动态值。包括登录用户和未登录用户
  audiences: [String],//意义同上，但只包括登录用户！！！
  resourceType: {type: String, default: 'broadcast'},//未用
  tags: [{name: String, code: Number}],//标签
  //位置信息
  lat: {type: Number, default: 0},
  lon: {type: Number, default: 0},
  //视频有关的参数
  height: {type: Number, default: 0},
  width: {type: Number, default: 0},
  length: {type: Number, default: 0},
  description: {type: String, default: ''},//资源描述
  permission: {type: String, default: 'public', enum: ['follower', 'public', 'private', '']}//not used
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

/**
 * 视频资源模型
 */
const videoResourceSchema = new Schema({
  v_owner: {type: Schema.Types.ObjectId, ref: 'user'},
  v_comments: [{type: Schema.Types.ObjectId, ref: 'comment'}],

  //资源标识.在主播资源时：主播id，又可做room id，从webhook得到（payload.id）。
  resourceId: {
    type: String,
    unique: true,
    required: true
  },
  resourceStatus: {
    type: String,
    default: 'na'
  },
  category: {type: String, default: ''},//分类
  userName: {type: String, default: ''},//小视频上或者图文作者名字
  userCode: {type: String, default: ''},//小视频上传者userCode
  uploadTime: {type: Number, default: 0},//上传时间
  likeCount: {type: Number, default: 0},//点赞(喜欢)数
  likes: [String],//likes userCode列表
  resourceUri: {type: String, default: ''},//resource uri
  preview: {type: imageSchema, default: emptyImage}, //preview photo url
  //以下4项可以计算得出
  commentCount: {type: Number, default: 0},//评论数
  followingCount: {type: Number, default: 0},//资源关注数
  favouriteCount: {type: Number, default: 0},//收藏数
  shareCount: {type: Number, default: 0},//分享计数仅对小视频和图文资源有效
  favourites: [String],//收藏者uuid
  shares: [shareSchema],
  resourceType: {type: String, default: 'video'},
  comments: [String],//commentId列表
  tags: [{name: String, code: Number}],
  music: {
    musicid: String,
    start: Number,
    end: Number,
  },
  fileSize: {type: String, default: ''},//文件尺寸,小视频?
  content: {type: String, default: ''},//内容?
  title: {type: String, default: ''},//本资源题目
  description: {type: String, default: ''},//资源描述
  //位置信息
  lat: {type: Number, default: 0},
  lon: {type: Number, default: 0},
  permission: {type: String, default: 'public', enum: ['follower', 'public', 'private', '']},
  deleted: {type: Boolean, default: false},
  amount: {type: Number, default: 0}, // 本条资源收到的礼物总量
  giftsReceived: [{ // 收到的礼物
    giftid: String,
    money: {type: Number, default: 0},
    transTime: {type: Number, default: 0},
    payerUserCode: String
  }]
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

/**
 * 图文资源模型
 */
const momentResourceSchema = new Schema({
  m_owner: {type: Schema.Types.ObjectId, ref: 'user'},
  m_comments: [{type: Schema.Types.ObjectId, ref: 'comment'}],

  //资源标识.在主播资源时：主播id，又可做room id，从webhook得到（payload.id）。
  resourceId: {
    type: String,
    unique: true,
    required: true
  },
  userName: {type: String, default: ''},//图文作者名字
  userCode: {type: String, default: ''},//上传者userCode
  uploadTime: {type: Number, default: 0},//时间
  likeCount: {type: Number, default: 0},//点赞(喜欢)数
  likes: [String],//userId列表
  followingCount: {type: Number, default: 0},//资源关注数
  favouriteCount: {type: Number, default: 0},//收藏数
  resourceType: {type: String, default: 'moment'},
  comments: [String],//commentId列表
  photoArray: [imageSchema],
  body: {type: String, default: ''},//内容
  //位置信息
  lat: {type: Number, default: 0},
  lon: {type: Number, default: 0},
  type: {type: String, default: 'text', enum: ['text', 'picture', 'video']},
  permission: {type: String, default: 'public', enum: ['follower', 'public', 'private', '']},
  mentionList: [String],
  deleted: {type: Boolean, default: false},
  amount: {type: Number, default: 0}, // 本条资源收到的礼物总量.可以设计SAVE.POST自动增加
  giftsReceived: [{ //收到的礼物
    giftid: String,
    money: {type: Number, default: 0},
    transTime: {type: Number, default: 0},
    payerUserCode: String
  }]
}, {
  toObject: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  },
  toJSON: {
    transform: function(doc, ret) {
      delete ret._id;
      delete ret.__v;
    }
  }
});

//关注人:follower/followering
//关注资源来,favourite
const UserSchema = new Schema({
  myVideos: [{type: Schema.Types.ObjectId, ref: 'videoResource'}],
  myMoments: [{type: Schema.Types.ObjectId, ref: 'momentResource'}],
  videoCount: {type: Number, default: 0},
  momentCount: {type: Number, default: 0},
  following: [String],//关注userCode集合
  follower: [String],//被关注userCode集合
  blocked: [String],//被locked userCode集合
  favourites: [String],//我的收藏夹,resourceId集合
  userLikeCount: {//暂时没用上？
    broadcast: {type: Number, default: 0},
    video: {type: Number, default: 0},
    moment: {type: Number, default: 0},
  },
  userResourceCount: {
    broadcast: {type: Number, default: 0},
    video: {type: Number, default: 0},
    moment: {type: Number, default: 0},
  },
  mobile: {type: String, default: ''},
  countryCode: {type: Number, default: 65},
  region: {type: String, default: ''},
  level: {type: Number, default: 0},
  language: {type: String, default: ''},
  birthday: {type: Number, default: 0},
  userCode: {
    type: String,
    unique: false,
    require: false
  },
  whatsup: {type: String, default: ''},
  name: {type: String, default: ''},
  nickName: {type: String, default: ''},
  gender: Number,
  facebook: {
    facebookId: String,
    expired: {type: Number, default: 0},
    token: String,
    picUrl: String
  },
  wechat: {
    openid: {type: String, default: ''},
    refresh_token: {type: String, default: ''},
    nickname: {type: String, default: ''},
    sex: Number,
    language: {type: String, default: ''},
    city: {type: String, default: ''},
    province: {type: String, default: ''},
    country: {type: String, default: ''},
    headimgurl: {type: String, default: ''},
    privilegde: [String],
    expired: {type: Number, default: 0},
    unionid: {type: String, default: ''}
  },
  password: {
    type: String,
    require: false,
    default: 'defaultpassword' + Date.now()
  },
  token: String,
  device: {type: deviceSchema, default: {}},
  //账号种类
  accountType: {
    type: String,
    default: 'mobile',
    enum: ['mobile', 'facebook', 'wechat', 'others', 'nologin', 'normal']
  },
  isEnabled: {type: Boolean, default: false},
  addressBook: [addressBookSchema],
  //角色信息
  /*
  0  normal
  1  admin
  2  broadcast
  3  little video
  4  moment
  there could be multiple roles
  e.g. admin can be both 2 and 3
  */
  roleType: {type: Number, default: 0},
  avatar: {type: imageSchema, default: emptyImage},
  publishedResources: {type: publishedResourceSchema, default: {}},
  interests: [String],
  email: {type: String, default: ''},
  logintime: {type: Number, default: 0},
  giftsReceived: [{
    giftid: String,
    money: {type: Number, default: 0},
    transTime: {type: Number, default: 0},
    payerUserCode: String,
    resourceId: String
  }],
  giftsSent: [{
    giftid: String,
    money: {type: Number, default: 0},
    transTime: {type: Number, default: 0},
    payeeUserCode: String,
    resourceId: String
  }],
  //用户现有钱包
  //当前只有亚洲支付货币.若有多币种.则要用数组
  amount: {type: Number, default: 0},
  tokbox: {type: tokboxSchema, default: {}},
}, {
  usePushEach: true
});

// 添加用户保存时中间件对password进行bcrypt加密,这样保证用户密码只有用户本人知道
UserSchema.pre('save', function(next) {
  var user = this;
  user.publishedResources.isLive = (user.tokbox.status === 'on');
  if(this.isModified('password') || this.isNew){
    bcrypt.genSalt(10, function(err, salt) {
      if(err){
        return next(err);
      }
      bcrypt.hash(user.password, salt, function(err, hash) {
        if(err){
          return next(err);
        }
        user.password = hash;
        next();
      });
    });
  } else {
    return next();
  }
});

// 校验用户输入密码是否正确
UserSchema.methods.comparePassword = function(passw, cb) {
  bcrypt.compare(passw, this.password, (err, isMatch) => {
    if(!this.isEnabled){
      return cb('user disabled');
    }
    if(err){
      return cb(err);
    }
    cb(null, isMatch);
  })
}

/**
 * 0 nothing
 * 1 me following the user (userCode)
 * 2 the user (userCode) following me
 * 3 bi-follower
 * @param me
 * @param userCode
 */
function followship(me, user) {
  let retval = 0;
  try {
    if(me.following.indexOf(user.userCode) >= 0){
      if(me.follower.indexOf(user.userCode) >= 0) retval = 3;
      else retval = 1
    }
    else if(me.follower.indexOf(user.userCode) >= 0) retval = 2;
  } catch(error) {
  }
  return retval;
}
var blocked = (me, user) => {
  try {
    return (me.blacked.indexOf(user.userCode) >= 0)
  } catch(error) {
  }
  return false;
}

UserSchema.methods.getprofile = function(me) {
  return {
    userCode: this.userCode,
    name: this.name,
    nickname: this.nickName,
    gender: this.gender,
    avatar: this.avatar,
    //直播信息
    category: this.publishedResources.category,
    resourceId: this.tokbox.sessionId,
    // resourceId: this.publishedResources.resourceId,
    resourceUri: this.publishedResources.resourceUri,
    // title: this.publishedResources.title,
    tags: this.publishedResources.tags,
    lat: this.publishedResources.lat,
    lon: this.publishedResources.lon,
    channelId: this.publishedResources.channelId,
    startTime: this.tokbox.stream.createdAt,
    coverImage: this.publishedResources.coverImage,
    description: this.publishedResources.description,
    ranking: this.publishedResources.ranking,
    followingCount: this.following.length,
    followerCount: this.follower.length,
    //favouritesCount: this.publishedResources.favourites.length,
    likeCount: this.publishedResources.likes.length,
    audienceCount: this.publishedResources.audiencesCount,
    roleType: this.roleType,
    countryCode: this.countryCode,
    accountType: this.accountType,
    mobile: this.mobile,
    birthday: this.birthday ? this.birthday : 0,
    region: this.region,
    logintime: this.logintime,
    whatsup: this.whatsup,
    giftsReceived: this.amount,
    interests: this.interests,
    followship: followship(me ? me : null, this),
    isAppUser: true,
    videoCount: this.videoCount,
    momentCount: this.momentCount,
    blocked: blocked(me,this)
  }
}
UserSchema.methods.getProfile_v1128 = function(me) {
  return {
    userCode: this.userCode,
    name: this.name,
    nickname: this.nickName,
    gender: this.gender,
    avatar: this.avatar,
    followingCount: this.following.length,
    followerCount: this.follower.length,
    roleType: this.roleType,
    accountType: this.accountType,
    birthday: this.birthday ? this.birthday : 0,
    region: this.region,
    logintime: this.logintime,
    whatsup: this.whatsup,
    giftsReceived: this.amount,
    interests: this.interests,
    isAppUser: true,
    videoCount: this.videoCount,
    momentCount: this.momentCount,
    followship: followship(me,this),
    blocked: blocked(me,this),
    coverImage: this.publishedResources.coverImage,
    description: this.publishedResources.description,
    category: this.publishedResources.category,
    channelId:this.publishedResources.channelId
  }
}

UserSchema.methods.getCreator_nopromise = function() {
  return {
    nickName: this.nickName,
    name: this.name,
    userCode: this.userCode,
    avatar: this.avatar,
    followingCount: this.following.length,
    followerCount: this.follower.length,
    videoCount: this.videoCount ? this.videoCount : 0,
    momentCount: this.momentCount ? this.momentCount : 0
  }
}
videoResourceSchema.methods.giftReceivedTotal = function() {
  var retval = 0;
  var gifts = this.giftReceived;
  gifts.forEach(g => {
    retval += g.money;
  })
  return retval;
}
/*momentResourceSchema.methods.giftReceivedTotal = function() {
  var retval = 0;
  var gifts = this.giftReceived;
  gifts.forEach(g => {
    retval += g.money;
  })
  return retval;
}*/
// const emptySchema = new Schema({});
module.exports = {
  videoList: mongoose.model('videoList', new Schema({}, {collection: 'videoList'})),
  momentList: mongoose.model('momentList', new Schema({}, {collection: 'momentList'})),
  viewVideos: mongoose.model('viewVideos', videoResourceSchema, 'viewVideos'),
  viewMoments: mongoose.model('viewMoments', momentResourceSchema, 'viewMoments'),
  viewComments: mongoose.model('viewComments', commentSchema, 'viewComments'),
  user: mongoose.model('user', UserSchema),
  favourite: mongoose.model('favourite', favouriteSchema),
  gift: mongoose.model('gift', giftSchema),
  music: mongoose.model('music', musicSchema),
  comment: mongoose.model('comment', commentSchema),
  transaction: mongoose.model('transaction', transactionSchema),
  momentResource: mongoose.model('momentResource', momentResourceSchema),
  videoResource: mongoose.model('videoResource', videoResourceSchema),
  broadcastResource: mongoose.model('broadcastResource', publishedResourceSchema),
  emptyImage: emptyImage,
  tokboxHistory: mongoose.model('tokboxHistory', tokboxHistorySchema),
  addressBook: mongoose.model('addressBook', addressBookSchema),
  abuseReport: mongoose.model('abuseReport', abuseReportSchema),
  tokbokTypeModel: tokboxTypeModel
}

